<template>
    <div>
        <h3>评论 {{ commentTotalCount }}</h3>
        <div class="flex mar-t-20">
            <div class="w-px-40 h-40 overflow-hidden radius-50 mar-r-10 flex justify-center align-center defaultBorder">
				<img :src="getAvatar" class="w-100 h100 img-normal" />
			</div>

            <ReplyComment
                ref="replyComment"
                @handleSendComment="handleSendComment"
            />
        </div>

        <div>
            <div v-if="list.length > 0">
                <div
                    v-for="item in list"
                    :key="item.commentId"
                    class="flex mar-t-20"
                >
                    <div class="w-px-40 h-40 overflow-hidden radius-50 mar-r-10">
                        <img :src="getCommentAvatar(item)" class="w-100 h100 img-normal" />
                    </div>

                    <div class="flex-1">
                        <div class="font-14">
                            <span class="dis-block color-999999">{{ item.nickName ? item.nickName : item.username }}</span>

                            <div v-if="getPicUrls(item.picUrls).length > 0" class="mar-t-5">
                                <div
                                    v-for="(pic, index) in getPicUrls(item.picUrls)"
                                    :key="index"
                                    class="mar-b-5"
                                >
                                    <img :src="pic" style="max-width: 200px;" />
                                </div>
                            </div>

                            <p class="mar-t-5">{{ item.content }}</p>
                        </div>

                        <div class="flex justify-between font-14 color-999999 mar-t-5">
                            <div class="flex align-center">
                                <span>{{ formatDatetime(item.createTime) }}</span>

                                <div
                                    :class="'flex align-center mar-l-10 cur-pointer hoverClass ' + (item.isLikeState === 0 ? '' : 'color-1e9fff')"
                                    @click="handleLikeComment(item)"
                                >
                                    <SvgIcons iconClass="like_icon" class="font-18 mar-b-1 mar-r-5"/>                                                        
                                    <span :class="item.isLikeState === 0 ? '' : 'color-1e9fff'">点赞</span>
                                </div>

                                <div class="flex align-center mar-l-10 hoverClass cur-pointer" @click="showChildCommentDialog(item)">
                                    <SvgIcons iconClass="comment" class="font-18 mar-r-5" />
                                    <span>评论</span>
                                </div>
                            </div>

                            <el-dropdown @command="handleCommand($event, item)">
                                <span class="cur-pointer hoverClass font-18">. . .</span>
                                <el-dropdown-menu slot="dropdown">
                                    <el-dropdown-item command="report">举报</el-dropdown-item>
                                    <el-dropdown-item v-if="item.userId === userInfo.id" command="delete">删除</el-dropdown-item>
                                </el-dropdown-menu>
                            </el-dropdown>
                        </div>

                        <!-- 子评论 -->
                        <template v-if="item.children && item.children.length > 0">
                            <template v-for="(j, i) in item.children">
                                <div
                                    v-if="i <= getShowChildComment(item)"
                                    :key="j.commentId"
                                    class="flex mar-t-20"
                                >
                                    <div class="w-px-40 h-40 overflow-hidden radius-50 mar-r-10">
                                        <img :src="getCommentAvatar(j)" class="w-100 h100 img-normal" />
                                    </div>

                                    <div class="flex-1">
                                        <div class="font-14">
                                            <div class="color-999999">
                                                <span>
                                                    {{ j.nickName ? j.nickName : j.username }}
                                                </span>

                                                <span v-if="item.commentId !== j.parentId"> 回复 {{ getReplyPersonName(item, j) }}</span>
                                            </div>
                                            
                                            <div v-if="getPicUrls(j.picUrls).length > 0" class="mar-t-5">
                                                <div
                                                    v-for="(img, l) in getPicUrls(j.picUrls)"
                                                    :key="l"
                                                    class="mar-b-5"
                                                >
                                                    <img :src="img" style="max-width: 200px;" />
                                                </div>
                                            </div>

                                            <p class="mar-t-5">{{ j.content }}</p>
                                        </div>

                                        <div class="flex justify-between font-14 color-999999 mar-t-5">
                                            <div class="flex align-center">
                                                <span>{{ formatDatetime(j.createTime) }}</span>

                                                <div
                                                    :class="'flex align-center mar-l-10 cur-pointer hoverClass ' + (j.isLikeState === 0 ? '' : 'color-1e9fff')"
                                                    @click="handleLikeComment(j)"
                                                >
                                                    <SvgIcons iconClass="like_icon" class="font-18 mar-b-1 mar-r-5"/>                                                        
                                                    <span :class="j.isLikeState === 0 ? '' : 'color-1e9fff'">点赞</span>
                                                </div>

                                                <div class="flex align-center mar-l-10 hoverClass cur-pointer" @click="showChildCommentDialog(j)">
                                                    <SvgIcons iconClass="comment" class="font-18 mar-r-5" />
                                                    <span>评论</span>
                                                </div>
                                            </div>

                                            <el-dropdown @command="handleCommand($event, j)">
                                                <span class="cur-pointer hoverClass">. . .</span>
                                                <el-dropdown-menu slot="dropdown">
                                                    <el-dropdown-item command="report">举报</el-dropdown-item>
                                                    <el-dropdown-item v-if="j.userId === userInfo.id" command="delete">删除</el-dropdown-item>
                                                </el-dropdown-menu>
                                            </el-dropdown>
                                        </div>
                                    </div>
                                </div>
                            </template>
                            
                            <div
                                v-if="item.children.length > maxShowChildCommentCount && !item.isShowAllChildComment"
                                class="flex justify-center mar-t-10 cur-pointer hoverClass font-14"
                                @click.stop="item.isShowAllChildComment = !item.isShowAllChildComment"
                            >
                                <span>点击展示 {{ item.children.length }} 条子评论</span>
                            </div>
                        </template>
                    </div>
                </div>
            </div>

            <!-- 评论加载 -->
            <div v-if="commentLoading" v-loading="commentLoading" class="mar-t-40 h-80"></div>

            <!-- 没有更多数据 -->
            <div
                v-if="total > 0 && !commentLoading && total === list.length"
                class="flex justify-center color-999999 mar-t-20 pad-30 font-14"
            >
                <span>没有更多评论了哦~</span>
            </div>

            <div
                v-if="total > 0 && !commentLoading && total > list.length"
                class="flex justify-center mar-t-40 cur-pointer hoverClass color-999999"
            >
                <div @click="loadMore()">加载更多 >></div>
            </div>

            <!-- 空数据 -->
            <div v-if="list.length === 0 && !commentLoading && total === 0">
                <el-empty description="暂无数据"></el-empty>
            </div>
        </div>

        <!-- 子评论弹窗 -->
        <el-dialog
			:title="child.title"
            :width="dialogWidth"
			:visible.sync="child.show"
            :close-on-click-modal="false"
			:before-close="cancelChildCommentDialog"
		>
			<div>
                <ReplyComment
                    ref="childComment"
                    @handleSendComment="handleSendComment"
                />
            </div>
		</el-dialog>

        <!-- 举报弹窗 -->
        <el-dialog
			:title="report.title"
            width="30%"
			:visible.sync="report.show"
            :close-on-click-modal="false"
			:before-close="cancelReportDialog"
		>
			<el-input type="textarea" v-model="report.content" placeholder="请输入举报理由" rows="5" maxlength="200" :resize="'none'" show-word-limit></el-input>
            <div slot="footer" class="dialog-footer">
                <el-button @click="cancelReportDialog()">取 消</el-button>
                <el-button type="primary" @click="reportDialog()">确 定</el-button>
            </div>
		</el-dialog>
    </div>
</template>

<script>
    import ReplyComment from '@/components/ReplyComment/index'
    import SvgIcons from '@/components/SvgIcons/index'
    import Utils from '@/utils/utils'
    import moment from 'moment'
    import 'moment/locale/zh-cn'

    import { mapState } from 'vuex'
    import { commentArticle, getCommentList, delComment, likeComment, getCommentTotalCount, reportComment } from '@/apis/article'

    export default {
        components: {
            ReplyComment,
            SvgIcons,
        },

        props: {
            // 文章id
            articleId: {
                type: String | Number,
                default: '',
            },

            // 文章作者id
            authorId: {
                type: String | Number,
                default: '',
            },
        },

        computed: {
            ...mapState({
				userInfo: state => state.user.userInfo, // 用户信息
				defaultAvatar: state => state.user.defaultAvatar, // 默认头像
				token: state => state.user.token,
                isLogin: state => state.user.isLogin,
			}),

            // 格式化当前时间
            formatDatetime() {
                return (dateTime) => {
                    if (!dateTime) return '';
                    
                    const now = moment();
                    const targetTime = moment(dateTime);
                    
                    // 如果时间差小于60秒，显示"刚刚"，否则使用fromNow
                    return now.diff(targetTime, 'seconds') < 60 ? '刚刚' : targetTime.fromNow();
                }
            },

            // 获取评论图片
            getPicUrls() {
                return (urls) => {
                    if (urls) {
                        let arr = urls.split(',')
                        let data = arr.map(item => process.env.VUE_APP_IMG_BASE_API + item)

                        return data
                    }

                    return []
                }
            },

            // 获取头像
            getAvatar() {
                return this.userInfo && this.userInfo.avatar ? process.env.VUE_APP_IMG_BASE_API + this.userInfo.avatar : this.defaultAvatar
            },

            // 获取评论头像
            getCommentAvatar() {
                return (item) => {
                    if (item.avatar) {
                        return process.env.VUE_APP_IMG_BASE_API + item.avatar
                    }

                    return this.defaultAvatar
                }
            },

            // 获取子评论回复人
            getReplyPersonName() {
                return (item, j) => {
                    let name = ''

                    item.children.forEach(h => {
                        if (h.userId === j.parentUserId) {
                            name = h.nickName ? h.nickName : h.username
                        }
                    })

                    return name
                }
            },

            // 获取显示多少子评论
            getShowChildComment() {
                return (item) => {
                    let count = 0
                    if (!item.isShowAllChildComment) {
                        count = this.maxShowChildCommentCount - 1
                    } else {
                        count = item.children.length - 1
                    }

                    return count
                }
            },
        },

        data() {
            return {
                pageLoading: false,	// 页面加载中
                list: [], // 评论列表
                currentPage: 1, // 当前页（父评论分页）
                pageSize: 3, // 每页条数（父评论分页）
                total: 0, // 总条数（父评论分页）
                commentLoading: false, // 评论加载中
                commentTotalCount: 0, // 父评论 + 子评论（所有的）
                maxShowChildCommentCount: 3, // 最大显示子评论条数
                dialogWidth: '35%', // 弹窗宽度

                // 子评论
                child: {
                    show: false, // 控制弹窗显示
                    title: '', // 弹窗标题
                    fRow: null, // 父评论信息
                },

                // 举报
                report: {
                    show: false, // 弹窗显示
                    title: '举报理由', // 弹窗标题
                    content: '', // 举报内容
                    commentId: null, // 举报的评论id
                },
            }
        },

        mounted() {
            this.setDialogWidth()
            window.addEventListener('resize', this.setDialogWidth)
        },
        beforeDestroy() {
            window.removeEventListener('resize', this.setDialogWidth)
        },

        methods: {
            // 弹窗宽度自适应
            setDialogWidth() {
                const screenWidth = window.innerWidth
                if (screenWidth <= 500) {
                    this.dialogWidth = '80%'
                } else if (screenWidth <= 800) {
                    this.dialogWidth = '75%'
                } else if (screenWidth <= 950) {
                    this.dialogWidth = '70%'
                } else if (screenWidth <= 1150) {
                    this.dialogWidth = '60%'
                } else if (screenWidth <= 1300) {
                    this.dialogWidth = '50%'
                } else if (screenWidth <= 1500) {
                    this.dialogWidth = '45%'
                } else if (screenWidth <= 1800) {
                    this.dialogWidth = '40%'
                } else {
                    this.dialogWidth = '35%'
                }
            },

            // 查询所有父子评论总数
            findCommentTotalCount() {
                getCommentTotalCount({ articleId: this.articleId }).then(res => {
                    this.commentTotalCount = res.data
                })
            },

            // 显示子评论弹窗
            showChildCommentDialog(row) {
                this.child.title = `回复‘${row.nickName ? row.nickName : row.username}’的评论`
                this.child.fRow = row
                this.child.show = true
            },

            // 取消子评论弹窗
            cancelChildCommentDialog() {
                this.child.title = ''
                this.child.fRow = null
                this.child.show = false
            },

            // 点赞评论
            handleLikeComment(row) {
                this.pageLoading = Utils.loading('操作中...')
                likeComment({ articleId: row.articleId, commentId: row.commentId }).then(res => {
                    this.pageLoading.close()
                    if (res.code === 200) {
                        if (row.isLikeState === 1) {
                            Utils.notifyPopUpMsg('info', '您已取消点赞！', '提示', 1000)
                        } else {
                            Utils.notifyPopUpMsg('success', '点赞成功！', '提示', 1000)
                        }
                        row.isLikeState = row.isLikeState === 1 ? 0 : 1
                    } else {
                        Utils.popUpMsg('error', res.msg, 1500)
                    }
                }).catch(err => {
                    this.pageLoading.close()
                })
            },

            // 操作
            handleCommand(command, row) {
                switch (command) {
                    case 'report':
                        this.showReportDialog(row.commentId)
                        break
                    case 'delete':
                        this.handleDelComment(row.commentId)
                        break
                }
            },

            // 打开举报弹窗
            showReportDialog(row) {
                this.report.commentId = row
                this.report.show = true
            },

            // 关闭举报弹窗
            cancelReportDialog(){
                this.report.title = ''
                this.report.content = ''
                this.report.show = false
            },

            // 确定举报评论
            reportDialog() {
                if (!this.report.content) {
                    Utils.popUpMsg('error', '请填写举报内容！', 1500)
                    return
                }

                let params = {
                    articleId: this.articleId,
                    commentId: this.report.commentId,
                    content: this.report.content
                }
                this.pageLoading = Utils.loading('正在举报中...')

                reportComment(params).then(res => {
                    this.pageLoading.close()
                    if (res.code === 200) {
                        Utils.popUpMsg('success', res.msg, 1500)
                        this.cancelReportDialog()
                    }
                }).catch(err => {
                    this.pageLoading.close()
                })
            },

            // 删除评论
            handleDelComment(commentId) {
                Utils.confirmPopUpMsg('warning', '您确定要删除此评论吗？', '删除评论', () => {
                    this.pageLoading = Utils.loading('正在删除此评论...')
                    delComment({ commentId, articleId: this.articleId }).then(res => {
                        this.pageLoading.close()
                        if (res.code === 200) {
                            Utils.popUpMsg('success', res.msg, 1500)
                            this.delCommentFront(commentId, this.list)
                            this.total--
                            this.commentTotalCount--
                            this.findCommentTotalCount() // 重新计算总评论数量
                        } else {
                            Utils.popUpMsg('error', res.msg, 3000)
                        }
                    }).catch(err => {
                        this.pageLoading.close()
                    })
                }, () => {
                    console.log('取消删除！')
                })
            },

            // 递归删除评论（为了不影响用户体验，前端需要在后端删除成功后去从列表中删除这个评论）
            delCommentFront(commentId, data) {
                if (data && data.length > 0) {
                    data.forEach((item, index) => {
                        if (item.commentId === commentId) {
                            return data.splice(index, 1)
                        } else {
                            if (item.children && item.children.length > 0) {
                                this.delCommentFront(commentId, item.children)
                            }
                        }
                    })
                }

                return data
            },

            // 删除评论成功后，处理数据，子评论没问题，只需要观察父评论变化
            handleDelData() {
                // 正常情况，不需要计算
                if (this.currentPage * this.pageSize === this.list.length) return
                if (this.currentPage * this.pageSize > this.list.length && this.list.length === this.total) return

                // 判断当前展示的数据，与分页数据总数是否一致
                if (this.currentPage * this.pageSize > this.list.length && this.list.length < this.total) {
                    // 表示删除评论后，当前分页展示数据不够
                    // 需要先告知删除的是那一页的数据（需要删除前计算），再调用查询评论列表数据得到那一页的新数据，然后再进行去重处理，就得到一个最新的补充的数据
                    // 将这个要补充的数据添加到列表即可
                }
            },

            // 加载更多评论
            loadMore() {
                if (this.currentPage < Math.ceil(this.total / this.pageSize)) {
                    this.currentPage++
                    this.findArticleCommentList()
                }
            },

            // 查询评论列表
            findArticleCommentList() {
                let params = {
                    articleId: this.articleId,
                    pageSize: this.pageSize,
                    currentPage: this.currentPage
                }

                this.commentLoading = true

                getCommentList(params).then(res => {
                    this.commentLoading = false
                    if (res.code === 200) {
                        let data = JSON.parse(JSON.stringify(this.list.concat(...res.data.rows)))

                        // 为所有顶级评论增加 isShowAllChildComment 字段，表示是否展示所有子评论，默认不展示
                        data.forEach(item => {
                            if (!item.rootId) {
                                item.isShowAllChildComment = false
                            }
                        })

                        this.list = this.mapData(data)
                        this.total = res.data.total
                    } else {
                        Utils.popUpMsg('error', res.msg, 3000)
                    }
                }).catch(err => {
                    this.commentLoading = false
                })
            },

            // 将评论列表中每一项都添加children字段
            mapData(data) {
                data.forEach(item => {
                    // 先递归处理子节点
                    if (item.children && item.children.length > 0) {
                        this.mapData(item.children)
                    }
                    
                    // 确保每个节点都有children字段
                    if (!item.children) {
                        item.children = []
                    }
                })

                return data
            },

            // 获取评论参数
            getQuerys(content, picUrls) {
                if (!this.articleId) {
                    Utils.popUpMsg('warning', '这篇文章不存在，请刷新！', 3000)
                    return false
                }

                if (!this.isLogin) {
                    Utils.popUpMsg('warning', '请登录！', 3000)
                    return false
                }

                if (!content) {
                    Utils.popUpMsg('warning', '请输入评论内容！', 3000)
                    return false
                }

                let params = {
                    articleId: this.articleId,
                    uid: this.authorId,
                    content,
                    picUrls,
                    parentId: '',
                }

                // 判断是否发送子评论
                if (this.child.show) {
                    params.parentId = this.child.fRow.commentId
                    params.rootId = !this.child.fRow.rootId ? this.child.fRow.commentId : this.child.fRow.rootId
                }

                return params
            },

            // 发送评论
            handleSendComment({ content, picUrls }) {
                if (!this.getQuerys(content, picUrls)) return
                this.pageLoading = Utils.loading('评论发送中，请稍等...')

                commentArticle(this.getQuerys(content, picUrls)).then(res => {
                    this.pageLoading.close()
                    if (res.code === 200) {
                        Utils.popUpMsg('success', res.msg, 1500)

                        // 为新增的评论添加 children 字段，为了新增子评论的时候使用
                        if (!res.data.children) {
                            res.data.children = []
                        }

                        // 为新增的顶级评论增加 isShowAllChildComment 字段，表示是否展示所有子评论，默认不展示
                        if (!res.data.rootId) {
                            res.data.isShowAllChildComment = false
                        }

                        this.handleCommentSuccess(res.data)
                    } else {
                        Utils.popUpMsg('error', res.msg, 3000)
                    }
                }).catch(err => {
                    this.pageLoading.close()
                })
            },

            // 新增子评论
            handleAddChildComment(data) {
                this.list.forEach(item => {
                    if (item.commentId === data.rootId) {
                        item.children.push(data)
                    }
                })
            },

            // 评论成功后的回调
            handleCommentSuccess(data) {
                // 将顶级评论置顶（一级评论）
                if (!data.rootId) {
                    this.list.unshift(data)
                    this.total++
                    this.commentTotalCount++
                } else {
                    this.handleAddChildComment(data)
                }

                // 如果当前页的评论数已经达到最大，则删除最后一条评论
                if (this.list.length > this.currentPage * this.pageSize) {
                    this.list.splice(this.list.length - 1, 1)
                }

                if (this.child.show) {
                    this.$refs.childComment.clearData()
                    this.cancelChildCommentDialog()
                } else {
                    this.$refs.replyComment.clearData()
                }

                this.findCommentTotalCount() // 重新计算总评论数量
            },
        }
    }
</script>

<style lang="scss" scoped>
	
</style>
